#!/usr/bin/env python

import os
import sys
import unittest
from pyrna.grammar import *


nt1 = NonTerminal('V1')
nt2 = NonTerminal('V1')
t1 = Terminal('1')
int1 = InterNonTerminal('u1', nt1, 'u2')
p1 = Production(nt1, [int1, nt2])
p2 = Production(nt1, [int1, nt2])
p3 = Production(nt2, [int1, nt1])
p4 = Production(nt2, [int1, t1])
p5 = Production(int1, [t1])
p6 = Production(nt1, [t1, nt1])


class NonTerminal_Test(unittest.TestCase):
    def setUp(self):
        self.nt1 = NonTerminal('V1')
        self.nt2 = NonTerminal('V1')
    
    def test_equal(self):
        assert id(self.nt1) != id(self.nt2)
        assert self.nt1 == self.nt2

    def test_hash(self):
        x = dict()
        for n in (self.nt1, self.nt2):
            if n not in x:
                x[n] = True
        assert len(x) == 1


class Terminal_Test(unittest.TestCase):
    def setUp(self):
        self.t1 = Terminal('1')
        self.t2 = Terminal('1')
    
    def test_equal(self):
        assert id(self.t1) != id(self.t2)
        assert self.t1 == self.t2

    def test_hash(self):
        x = dict()
        for n in (self.t1, self.t2):
            if n not in x:
                x[n] = True
        assert len(x) == 1
        
        nt3 = NonTerminal('1')
        assert nt3 not in x


class InterNonTerminal_Test(unittest.TestCase):
    def setUp(self):
        self.int1 = int1
        self.int2 = InterNonTerminal('u1', nt1, 'u2')
    
    def test_equal(self):
        assert id(self.int1) != id(self.int2)
        assert self.int1 == self.int2

    def test_hash(self):
        x = dict()
        for n in (self.int1, self.int2):
            if n not in x:
                x[n] = True
        assert len(x) == 1


class Production_Test(unittest.TestCase):
    def setUp(self):
        self.p1 = p1
        self.p2 = p2
        self.p3 = p3
        self.p4 = p4
    
    def test_equal(self):
        assert id(self.p1) != id(self.p2)
        assert self.p1 == self.p2
        assert self.p1 == self.p3
        assert self.p1 != self.p4
    
    def test_hash(self):
        x = dict()
        plist = (self.p1, self.p2, self.p3, self.p4)
        for n in plist:
            if n not in x:
                x[n] = True
        assert len(x) == 2
        
        
class Grammar_Test(unittest.TestCase):
    def setUp(self):
        axiom = NonTerminal('S1')
        self.g = Grammar(axiom, [p1, p2, p3, p4, p5, p6])
        
    def test_num(self):
        assert self.g.num_nt() == 2
        
    def test_num_prod(self):
        assert self.g.num_prod() == 4    
        
    def test_productions(self):
        assert len(self.g.productions(leftHandSide=int1)) == 1
        assert len(self.g.productions(rightHandSide=(t1,))) == 2
        assert len(self.g.productions(rightHandSide=(int1,))) == 2
        assert len(self.g.productions(rightHandSide=p5.rightHandSide())) == 2 
        assert len(self.g.productions(leftHandSide=int1, 
            rightHandSide=p5.rightHandSide())) == 1
        
    def test_index(self):
        assert len(self.g._leftHandSideIndex) == 2
        assert len(self.g._rightHandSideIndex) == 2
  

if __name__ == '__main__':
    unittest.main()
            